{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import mediapipe.framework.calculator_pb2 as calculator_pb2\n",
    "from google.protobuf import text_format"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "pb = \"\"\"# Images coming into and out of the graph.\n",
    "input_stream: \"input_video\"\n",
    "output_stream: \"output_video\"\n",
    "\n",
    "# Converts RGB images into luminance images, still stored in RGB format.\n",
    "node: {\n",
    "  calculator: \"LuminanceCalculator\"\n",
    "  input_stream: \"input_video\"\n",
    "  output_stream: \"luma_video\"\n",
    "}\n",
    "\n",
    "# Applies the Sobel filter to luminance images sotred in RGB format.\n",
    "node: {\n",
    "  calculator: \"SobelEdgesCalculator\"\n",
    "  input_stream: \"luma_video\"\n",
    "  output_stream: \"output_video\"\n",
    "}\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "graph = calculator_pb2.CalculatorGraphConfig()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(<google.protobuf.pyext._message.MessageDescriptor at 0x184b3e6dfc8>,\n",
       " <google.protobuf.pyext._message.FileDescriptor at 0x184b3af9388>,\n",
       " <google.protobuf.pyext._message.MessageDescriptor at 0x184b3e6dfc8>)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "calculator_pb2.CalculatorGraphConfig.DESCRIPTOR,calculator_pb2.DESCRIPTOR,graph.DESCRIPTOR"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "node {\n",
       "  calculator: \"LuminanceCalculator\"\n",
       "  input_stream: \"input_video\"\n",
       "  output_stream: \"luma_video\"\n",
       "}\n",
       "node {\n",
       "  calculator: \"SobelEdgesCalculator\"\n",
       "  input_stream: \"luma_video\"\n",
       "  output_stream: \"output_video\"\n",
       "}\n",
       "input_stream: \"input_video\"\n",
       "output_stream: \"output_video\""
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "text_format.Merge(pb, graph)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**subgraph**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from google.protobuf import descriptor_pool\n",
    "from google.protobuf import descriptor\n",
    "from google.protobuf import descriptor_pb2\n",
    "from mediapipe.calculators.core import packet_resampler_calculator_pb2\n",
    "from google.protobuf.pyext import _message\n",
    "from pathlib import Path\n",
    "import importlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# pool=descriptor_pool.Default()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "# files = [x for x in Path(\"mediapipe\").glob(\"**/*\") if x.suffix == '.py']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "# file = files[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "# '.'.join(file.parts)\n",
    "# aa = importlib.import_module('.'.join(file.parts).rstrip('.py'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<google.protobuf.pyext._message.FileDescriptor at 0x229b10865c8>"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# aa.__dict__.get(\"DESCRIPTOR\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "No module named 'mediapipe.gpu'\n",
      "No module named 'mediapipe.util'\n",
      "No module named 'mediapipe.util'\n",
      "No module named 'mediapipe.util'\n",
      "No module named 'mediapipe.util'\n",
      "No module named 'mediapipe.util'\n",
      "No module named 'mediapipe.util'\n",
      "No module named 'mediapipe.util'\n",
      "No module named 'mediapipe.util'\n",
      "No module named 'mediapipe.util'\n",
      "No module named 'mediapipe.util'\n",
      "No module named 'mediapipe.util'\n",
      "No module named 'mediapipe.util'\n",
      "No module named 'mediapipe.framework.deps'\n"
     ]
    }
   ],
   "source": [
    "def register_descriptor(root):\n",
    "    for file in Path(root).glob(\"**/*\"):\n",
    "        pool=descriptor_pool.Default()\n",
    "        from google.protobuf.pyext import _message\n",
    "        if file.suffix == '.py':\n",
    "    #         print(file, file.suffix)\n",
    "            try:\n",
    "                aa = importlib.import_module('.'.join(file.parts).rstrip('.py'))\n",
    "            except Exception as e:\n",
    "                print(e)\n",
    "            bb = aa.__dict__.get(\"DESCRIPTOR\")\n",
    "            if bb is not None and isinstance(bb, _message.FileDescriptor):\n",
    "                pool.AddFileDescriptor(bb)\n",
    "register_descriptor('mediapipe')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "# pool.AddDescriptor(calculator_pb2.CalculatorGraphConfig.DESCRIPTOR)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<google.protobuf.pyext._message.FileDescriptor at 0x229ae05bbc8>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# pool.AddFileDescriptor(packet_resampler_calculator_pb2.DESCRIPTOR)\n",
    "# packet_resampler_calculator_pb2.DESCRIPTOR"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "# pool.AddDescriptor(packet_resampler_calculator_pb2.PacketResamplerCalculatorOptions.DESCRIPTOR)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(mediapipe.framework.calculator_pb2.CalculatorGraphConfig,\n",
       " google.protobuf.pyext.cpp_message.GeneratedProtocolMessageType)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# type(graph),type(calculator_pb2.CalculatorGraphConfig)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "pb = \"\"\"\n",
    "# MediaPipe graph that performs object detection and tracking with TensorFlow\n",
    "# Lite on CPU.\n",
    "# Used in the examples in\n",
    "# mediapipie/examples/desktop/object_tracking/\n",
    "\n",
    "# Images on CPU coming into and out of the graph.\n",
    "input_stream: \"input_video\"\n",
    "output_stream: \"output_video\"\n",
    "\n",
    "# Resamples the images by specific frame rate. This calculator is used to\n",
    "# control the frequecy of subsequent calculators/subgraphs, e.g. less power\n",
    "# consumption for expensive process.\n",
    "node {\n",
    "  calculator: \"PacketResamplerCalculator\"\n",
    "  input_stream: \"DATA:input_video\"\n",
    "  output_stream: \"DATA:throttled_input_video\"\n",
    "  node_options: {\n",
    "    [type.googleapis.com/mediapipe.PacketResamplerCalculatorOptions] {\n",
    "      frame_rate: 3\n",
    "    }\n",
    "  }\n",
    "}\n",
    "\n",
    "# Subgraph that detections objects (see object_detection_cpu.pbtxt).\n",
    "node {\n",
    "  calculator: \"ObjectDetectionSubgraphCpu\"\n",
    "  input_stream: \"IMAGE:throttled_input_video\"\n",
    "  output_stream: \"DETECTIONS:output_detections\"\n",
    "}\n",
    "\n",
    "# Subgraph that tracks objects (see object_tracking_cpu.pbtxt).\n",
    "node {\n",
    "  calculator: \"ObjectTrackingSubgraphCpu\"\n",
    "  input_stream: \"VIDEO:input_video\"\n",
    "  input_stream: \"DETECTIONS:output_detections\"\n",
    "  output_stream: \"DETECTIONS:tracked_detections\"\n",
    "}\n",
    "\n",
    "# Subgraph that renders annotations and overlays them on top of input images (see renderer_cpu.pbtxt).\n",
    "node {\n",
    "  calculator: \"RendererSubgraphCpu\"\n",
    "  input_stream: \"IMAGE:input_video\"\n",
    "  input_stream: \"DETECTIONS:tracked_detections\"\n",
    "  output_stream: \"IMAGE:output_video\"\n",
    "}\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "graph = calculator_pb2.CalculatorGraphConfig()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "node {\n",
       "  calculator: \"PacketResamplerCalculator\"\n",
       "  input_stream: \"DATA:input_video\"\n",
       "  output_stream: \"DATA:throttled_input_video\"\n",
       "  node_options {\n",
       "    type_url: \"type.googleapis.com/mediapipe.PacketResamplerCalculatorOptions\"\n",
       "    value: \"\\t\\000\\000\\000\\000\\000\\000\\010@\"\n",
       "  }\n",
       "}\n",
       "node {\n",
       "  calculator: \"ObjectDetectionSubgraphCpu\"\n",
       "  input_stream: \"IMAGE:throttled_input_video\"\n",
       "  output_stream: \"DETECTIONS:output_detections\"\n",
       "}\n",
       "node {\n",
       "  calculator: \"ObjectTrackingSubgraphCpu\"\n",
       "  input_stream: \"VIDEO:input_video\"\n",
       "  input_stream: \"DETECTIONS:output_detections\"\n",
       "  output_stream: \"DETECTIONS:tracked_detections\"\n",
       "}\n",
       "node {\n",
       "  calculator: \"RendererSubgraphCpu\"\n",
       "  input_stream: \"IMAGE:input_video\"\n",
       "  input_stream: \"DETECTIONS:tracked_detections\"\n",
       "  output_stream: \"IMAGE:output_video\"\n",
       "}\n",
       "input_stream: \"input_video\"\n",
       "output_stream: \"output_video\""
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "text_format.Merge(pb, graph,allow_unknown_extension=True, allow_unknown_field=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "b'\\t\\x00\\x00\\x00\\x00\\x00\\x00\\x08@'"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph.node[0].node_options[0].value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
